# Copyright (c) Sualeh Fatehi
# SPDX-License-Identifier: EPL-2.0

import re
import java

# Import Java classes if needed
# For example, if you use these types in Java interop:
# TableRelationshipType = java.type("schemacrawler.schema.TableRelationshipType")

print("@startuml")
print("""
!theme plain
hide empty methods

!procedure $schema($name, $slug)
package "$name" as $slug <<Rectangle>>
!endprocedure

!procedure $table($name, $slug)
entity "<b>$name</b>" as $slug << (T, Orange) table >>
!endprocedure

!procedure $view($name, $slug)
entity "<b>$name</b>" as $slug << (V, Aquamarine) view >>
!endprocedure

!procedure $pk($name)
<color:#GoldenRod><&key></color> <b>$name</b>
!endprocedure

!procedure $fk($name)
<color:#Silver><&key></color> $name
!endprocedure

!procedure $column($name)
{field} <color:#Transparent><&media-record></color> $name
!endprocedure

""")

print('title "' + title + '"')
print('')
print('legend bottom right')
print('generated by ' + catalog.getCrawlInfo().getSchemaCrawlerVersion().toString())
print('generated on ' + catalog.getCrawlInfo().getCrawlTimestamp())
print('end legend')
print('')
print('')

# Tables
for schema in catalog.getSchemas():
    if not catalog.getTables(schema):
        continue
    print('$schema("' + re.sub(r'\"', '', schema.getFullName()) + '", "' + schema.key().slug() + '") {')
    print('')
    for table in catalog.getTables(schema):
        if not table.getTableType().isView():
            print('$table', end='')
        else:
            print('$view', end='')
        print('("' + re.sub(r'\"', '', table.getName()) + '", "' + table.key().slug() + '") {')
        for column in table.getColumns():
            if column.isPartOfPrimaryKey():
                print('  $pk', end='')
            elif column.isPartOfForeignKey():
                print('  $fk', end='')
            else:
                print('  $column', end='')
            print('("' + column.getName() + '"): ' + column.getColumnDataType().getName(), end='')
            print(' ', end='')
            if not column.isNullable():
                print('NOT NULL', end='')
            print('')
        print('}')
        print('')
        if table.getRemarks() is not None and len(table.getRemarks()) > 0:
            print('note left of ' + table.key().slug() + ' #LemonChiffon')
            print(table.getRemarks())
            print('end note')
            print('')
        for column in table.getColumns():
            if column.getRemarks() is not None and len(column.getRemarks()) > 0:
                print('note right of ' + table.key().slug() + '::' + column.getName() + ' #LightCyan')
                print(column.getRemarks())
                print('end note')
                print('')
        print('')
        print('')
    print('')
    print('}')
    print('')
    print('')

# Foreign keys
for table in catalog.getTables():
    for fk in table.getExportedForeignKeys():
        pkTable = fk.getPrimaryKeyTable()
        fkTable = fk.getForeignKeyTable()
        for columnReference in fk.getColumnReferences():
            pkColumn = columnReference.getPrimaryKeyColumn()
            fkColumn = columnReference.getForeignKeyColumn()
            print(pkTable.getSchema().key().slug() + '.' +
                  pkTable.key().slug() + '::' +
                  re.sub(r'\"', '', pkColumn.getName()) +
                  '  ||--o{ ' +
                  fkTable.getSchema().key().slug() + '.' +
                  fkTable.key().slug() + '::' +
                  re.sub(r'\"', '', fkColumn.getName()), end='')
            if fk.getName() and not fk.getName().startswith('SCHCRWLR_'):
                print(' : ' + fk.getName(), end='')
            print('')
print('')

print("@enduml")
